
package cn.iocoder.yudao.module.apijson.framework;

import apijson.Log;
import apijson.NotNull;
import apijson.orm.AbstractFunctionParser;
import apijson.orm.script.ScriptExecutor;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.rmi.ServerException;


/**
 * 启动入口 Application
 * 右键这个类 > Run As > Java Application
 *
 * @author Lemon
 */
@Slf4j
public class APIJSONApplication {
    public static final String TAG = "APIJSONApplication";

    @NotNull
    public static APIJSONCreator DEFAULT_APIJSON_CREATOR;

    static {
        DEFAULT_APIJSON_CREATOR = new APIJSONCreator();
    }

    public static APIJSONParser createParser() {
        return DEFAULT_APIJSON_CREATOR.createParser();
    }


    public static APIJSONFunctionParser createFunctionParser() {
        return DEFAULT_APIJSON_CREATOR.createFunctionParser();
    }


    public static APIJSONVerifier createVerifier() {
        return DEFAULT_APIJSON_CREATOR.createVerifier();
    }


    public static APIJSONSQLConfig createSQLConfig() {
        return DEFAULT_APIJSON_CREATOR.createSQLConfig();
    }


    public static APIJSONSQLExecutor createSQLExecutor() {
        return DEFAULT_APIJSON_CREATOR.createSQLExecutor();
    }


    /**
     * 初始化，加载所有配置并校验
     */
    public static void init() throws Exception {
        init(true, DEFAULT_APIJSON_CREATOR);
    }

    /**
     * 初始化，加载所有配置并校验
     */
    public static void init(boolean shutdownWhenServerError) throws Exception {
        init(shutdownWhenServerError, DEFAULT_APIJSON_CREATOR);
    }

    /**
     * 初始化，加载所有配置并校验
     */
    public static void init(
            @NotNull APIJSONCreator creator) throws Exception {
        init(true, creator);
    }

    /**
     * 初始化，加载所有配置并校验
     */
    public static void init(
            boolean shutdownWhenServerError, @NotNull APIJSONCreator creator) throws Exception {
        log.info("<<<<<<<<<<<<<<<<<<<<<<<<< APIJSON 开始启动 >>>>>>>>>>>>>>>>>>>>>>>>");
        DEFAULT_APIJSON_CREATOR = creator;

        if (APIJSONVerifier.ENABLE_VERIFY_ROLE) {
            log.info("开始初始化: Access 权限校验配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
            try {
                APIJSONVerifier.initAccess(shutdownWhenServerError, creator);
            } catch (Throwable e) {
                log.error("Access 权限校验配置 启动失败！", e);
                if (shutdownWhenServerError) {
                    onServerError("Access 权限校验配置 初始化失败！", shutdownWhenServerError);
                }
            }
            log.info("完成初始化: Access 权限校验配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        }


        if (APIJSONFunctionParser.ENABLE_REMOTE_FUNCTION) {
            log.info("开始初始化: Function 远程函数配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
            try {
                APIJSONFunctionParser.init(shutdownWhenServerError, creator);
            } catch (Throwable e) {
                log.error("Function 远程函数配置 启动失败！", e);
                if (shutdownWhenServerError) {
                    onServerError("Function 远程函数配置 初始化失败！", shutdownWhenServerError);
                }
            }
            log.info("完成初始化: Function 远程函数配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

            log.info("开始测试: Function 远程函数 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
            try {
                APIJSONFunctionParser.test();
            } catch (Throwable e) {
                log.error("Function 远程函数配置 测试失败！", e);
                if (shutdownWhenServerError) {
                    onServerError("Function 远程函数配置 测试失败！", shutdownWhenServerError);
                }
            }
            log.info("完成测试: Function 远程函数 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        }


        if (APIJSONVerifier.ENABLE_VERIFY_CONTENT) {
            log.info("开始初始化: Request 请求参数校验配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
            try {
                APIJSONVerifier.initRequest(shutdownWhenServerError, creator);
            } catch (Throwable e) {
                log.error("Request 请求参数校验配置 启动失败！", e);
                if (shutdownWhenServerError) {
                    onServerError("Request 请求参数校验配置 初始化失败！", shutdownWhenServerError);
                }
            }
            log.info("完成初始化: Request 请求参数校验校验配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");

            log.info("开始测试: Request 请求参数校验 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
            try {
                APIJSONVerifier.testStructure();
            } catch (Throwable e) {
                log.error("Request 请求参数校验 测试失败！", e);
                if (shutdownWhenServerError) {
                    onServerError("Request 请求参数校验 测试失败！", shutdownWhenServerError);
                }
            }
            log.info("完成测试: Request 请求参数校验 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        }

        if (APIJSONVerifier.ENABLE_APIJSON_ROUTER) {
            log.info("开始初始化: Document 请求映射配置 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
            try {
                APIJSONVerifier.initDocument(shutdownWhenServerError, creator);
            } catch (Throwable e) {
                log.error("Document 请求映射配置 启动失败！", e);
                if (shutdownWhenServerError) {
                    onServerError("Document 请求映射配置 初始化失败！", shutdownWhenServerError);
                }
            }
            log.info("完成初始化: Document 请求映射配置 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        }
        log.info("<<<<<<<<<<<<<<<<<<<<<<<<< APIJSON 启动完成，试试调用零代码万能通用 API 吧 ^_^ >>>>>>>>>>>>>>>>>>>>>>>>");
    }

    protected static void onServerError(String msg, boolean shutdown) throws ServerException {
        Log.e(TAG, "启动时自检测试未通过！原因：\n" + msg);

        if (shutdown) {
            System.exit(1);
        } else {
            throw new ServerException(msg);
        }
    }

    public static void addScriptExecutor(String language, ScriptExecutor<Long, JSONObject, JSONArray> scriptExecutor) {
        scriptExecutor.init();
        AbstractFunctionParser.SCRIPT_EXECUTOR_MAP.put(language, scriptExecutor);
    }


}
